import re
import grammar.ckyparser3 as gr
from nltk.corpus import wordnet as wn
import nltk

my_grammar=gr.gen_grammar('')

ques_words=['what','where','why','when','who','whom','which','how','name']

ans_point_rules={"who":"PERSON",
"whom":"PERSON",
"when":"DATE",
"where":"GPE",
"what place":"GPE",
"what time":"TIME",
"what day":"DAY",
"what month":"MONTH",
"which month":"MONTH",
"what age":"AGE",
"how old":"AGE",
"what brand":"PRODUCT",
"how far":"LENGTH",
"how tall":"LENGTH",
"how high":"LENGTH",
"how large":"AREA",
"how big":"AREA",
"how small":"AREA",
"how heavy":"WEIGHT",
"how rich":"MONEY",
"how often":"FREQUENCY",
"how many":"NUMBER",
"how long":"LENGTH/DURATION",
"why":"REASON"
}

what_rule="W[A-Z\$]* (VB[A-Z]? )?(CD )?(DT )?(JJ[A-Z]? )*(NN[A-Z]* )*"
where_rule="W[A-Z\$]* VB[A-Z]?"
when_rule="W[A-Z\$]* VB[A-Z]?"
why_rule="W[A-Z\$]* VB[A-Z]?"
who_rule="W[A-Z\$]* (RB[A-Z]? )?(VB[A-Z]? )|MD "
whom_rule="W[A-Z\$]* (RB[A-Z]? )?(VB[A-Z]? )|MD "
which_rule="W[A-Z\$]* (DT )?(JJ[A-Z]? )*(NN[A-Z]* )*"
how_rule="W[A-Z\$]* (JJ[A-Z]? )*(NN[A-Z]* )*|(RB[A-Z]? )((VB[A-Z]? )|MD )"
name_rule="(DT )?(JJ[A-Z]? )*(NN[A-Z]* )*"


rule_dict={"whom":whom_rule,"who":who_rule,"what":what_rule,"where":where_rule,"when":when_rule,"why":why_rule,"which":which_rule,"how":how_rule,"name":name_rule}

def question_point(tagged_list):
	ques_word=""
	ans_type="UNKNOWN"
	for tagged_word_tuples in tagged_list:
		tagged_word=tagged_word_tuples[0]
		for i in ques_words:
			if tagged_word.lower()==i:
				ques_word=i
				break
		if ques_word != "":
			break
	
	if ques_word=="" :
		return ans_type
		
	ques_tag_pattern=""
	for i in tagged_list:
		ques_tag_pattern+=i[1]
		ques_tag_pattern+=" "
	
	ques_pattern=""
	for i in tagged_list:
		ques_pattern+=i[0].lower()
		ques_pattern+=" "
		
	for i in ans_point_rules.keys():
		if ques_pattern.find(i) >= 0:
			ans_type=ans_point_rules[i]
			
	return ans_type
	
def find_question_focus(tagged_list):
	"""analyze the question and try to find a question focus
	"""
	ptable,plist=gr.ckyparse(tagged_list,my_grammar)
	tree,prob=gr.get_parse_tree(ptable,plist)
	if tree ==None:
		print 'No parse for the sentence'
		return
	focuz=top_down_parse(tree)
	return focuz
	


def top_down_parse(tree):
	"""analyzes the tree from top to bottom looking for specific rules
	"""
	grammar_rule=get_grammar_rule(tree)
	if grammar_rule==['ROOT','IN','ROOT']:
		return(top_down_parse(tree[2]))
	
	elif grammar_rule==['ROOT','WWP','FOLLOW']:
		tmp1=get_grammar_rule(tree[1])
		#print tmp1
		#print tree
		if tmp1==['WWP','WWORD']:
			np=get_np(tree[2][1][1])	#[2]=follow,[1]=sq,[1]=s
			leaf_word=get_leaves(tree[1])
			return ['NP',np,leaf_word]  #eg: NP city which
		elif tmp1==['WWP','WWORD','JWORD'] or tmp1==['WWP','WWORD','RBP']:
			leaf_word=get_leaves(tree[1])
			np=get_np(tree[2][1][1])
			return ['ENTITY',np,leaf_word]
	
	elif grammar_rule==['ROOT','S'] or grammar_rule==['ROOT','S','.']:
		tmp1=get_grammar_rule(tree[1])
		if tmp1==['S','ANO','NP']:
			leaf_word=get_leaves(tree[1][1])
			if leaf_word.lower().find('give') or leaf_word.lower().find('show') or leaf_word.lower().find('list') or leaf_word.lower().find('display'):
				np=get_np(tree[1][2])
				return ['DISPLAY',np,leaf_word]
			else:
				print "Cannot understand ",leaf_word
				return None
		else:
			print  "TO DOOOOOOOOOOOOOOO"
			return None
def get_np(tree):
	"""return the main noun phrase in the given tree
	"""
	if len(tree)==1:
		return
	else:
		rul=get_grammar_rule(tree)
		if rul[0]=='NP':
			if rul[1]!='NP':
				return get_leaves(tree).rstrip()
			
		tmp_np=get_np(tree[1])
		if tmp_np!=None:
			return tmp_np.rstrip()
		elif len(tree)==3:
			tmp_np=get_np(tree[2])
			if tmp_np!=None:
				return tmp_np.rstrip()
			else:
				return None

def get_leaves(node):
	"""returns the leaves under the current node passed
	"""
	l=''
	if len(node)==3:
		l+=get_leaves(node[1])
		l+=get_leaves(node[2])
	elif len(node)==2:
		l+=get_leaves(node[1])
	else:
		l+=node[0]
		l+=' '
	
	return l
	

def get_grammar_rule(tree):
	"""returns the current rule in the grammar
	"""
	count=0
	grammar_rule=[]
	for i in tree:
		if type(i)!=list:
			grammar_rule.append(i)
		else:
			grammar_rule.append(i[0])
		count+=1
	return grammar_rule


def get_main_noun(np):
	"""returns the main noun(s) in the noun phrase
	"""
	if np==None:
		return 
	toks=nltk.word_tokenize(np)
	tags=nltk.pos_tag(toks)
	main_noun=''
	for i in tags:
		if i[1].find('NN') != -1:
			main_noun+=i[0]
			main_noun+=' '
	return main_noun.rstrip()
def get_qp_from_np(main_noun):
	""" tries to find a question point using wordnet
	"""
	print 'trying to get qp from : ',main_noun
	if main_noun==None:
		return 
	flag=0
	for syns in wn.synsets(main_noun):
		if syns.lexname=='noun.location':
			return 'GPE'
		elif syns.lexname=='noun.animal' or syns.lexname=='noun.body' or syns.lexname=='noun.person' or syns.lexname=='adj.pert':
			return 'PERSON'
		elif syns.lexname=='noun.plant' or syns.lexname=='noun.artifact':
			return 'OBJECT'
		elif syns.lexname=='noun.time':
			if main_noun.lower()=='month':
				return 'MONTH'
			else:
				return 'DATE'
				
	
	return None

def ques_word_present(s):
	"""determines if the question is of the form wh-
	"""
	q_words=['where','when','who','whom','which','name']
	
	t=s.lower().split()
	for w in t:
		for q in q_words: 
			if w==q:
				return 1
	return 0

def ques_about_person(words):
	"""tries to find if words contain a proper noun
	"""
	toks=nltk.word_tokenize(words)
	tags=nltk.pos_tag(toks)
	flag=0
	name=[]
	for i in tags:
		if i[1].find('NNP') !=-1:
			flag=1
			name.append(i[0])
			
	return [flag,name]

def w_or_h_ques(s):
	"""tries to determine if it is a what or how question
	"""
	l=s.split()
	for i in l:
		k=i.lower()
		if k=='what' or k=='how' or k=='show' or k=='list' or k=='display':
			return 1
	return 0

def is_descriptive_ques(s):
	"""tries to determine if s has descriptive tyype question features
	"""
	return 1
	
def modify_query(orig_query):

    modify_list={}
    sub="XXXXX"
    pattern1="\s'[^\n]+'\s"
    pattern2='\s"[^\n]+"\s'
    res_pattern=pattern1+"|"+pattern2
    sub_list=re.findall(res_pattern,orig_query)

    for i in sub_list:
        tmp=re.sub(i," "+sub+" ",orig_query,1)
        modify_list.update({sub:i})
        orig_query=tmp
        sub+="X"

    return (orig_query,modify_list)

def draw_parse_tree(t,space='   '):
	"""draws the parse tree
	"""
	count=0
	for i in t:
		if type(i)!=list:
			print i,
		else:
			print '\n.',space,'(',
			draw_parse_tree(i,space+" . ")
			print ')',

